package org.example.cdpcrpbackend.controller;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.cdpcrpbackend.controller.dto.*;
import org.example.cdpcrpbackend.domain.Class;
import org.example.cdpcrpbackend.domain.*;
import org.example.cdpcrpbackend.service.*;
import org.example.cdpcrpbackend.util.JwtTool;
import org.example.cdpcrpbackend.util.MyType;
import org.example.cdpcrpbackend.util.excel.StudentUploadListener;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/admin")
@RequiredArgsConstructor
public class AdminController {
    // 学校管理员
    private final AdminService adminService;
    // 班级管理员
    private final ClassService classService;
    // 部门管理员
    private final DepartmentService departmentService;
    // 其他
    private final CrpModuleService crpModuleService;
    private final CrpItemService crpItemService;
    private final StudentService studentService;
    private final ScoreRecordService scoreRecordService;

    /**
     * 学校管理员登录、班级管理员登录、部门管理员登录
     */
    @PostMapping("/login")
    public Result login(@RequestBody LoginRequest body) {
        String md5Password = SecureUtil.md5(body.getPassword());
        String role = body.getRole();
        AdminInfo loginInfo;
        switch (role) {
            case MyType.RoleAdmin:
                loginInfo = adminService.login(body.getUsername(), md5Password);
                break;
            case MyType.RoleClass:
                loginInfo = classService.login(body.getUsername(), md5Password);
                break;
            case MyType.RoleDepartment:
                loginInfo = departmentService.login(body.getUsername(), md5Password);
                break;
            default:
                loginInfo = null;
        }
        if (loginInfo == null) {
            return Result.fail("登录失败");
        } else {
            // 设置 username
            loginInfo.setUsername(body.getUsername());
            // 设置 JWT
            String token = JwtTool.createToken(body.getUsername());
            loginInfo.setToken(token);
            return Result.success(loginInfo);
        }
    }

    /**
     * 获取所有模块，带有分页
     */
    @GetMapping("/crp-module-list")
    public Result crpModuleList(
            @RequestParam(value = "key", required = false, defaultValue = "") String key,
            @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
            @RequestParam(value = "size", required = false, defaultValue = "10") Integer size) {
        LambdaQueryWrapper<CrpModule> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(CrpModule::getName, key);
        List<CrpModule> list = crpModuleService.listByPage(wrapper, page, size);
        PageInfo<CrpModule> info = new PageInfo<>(list);
        return Result.success(info);
    }

    /**
     * 获取单个模块
     */
    @GetMapping("/crp-module/{id}")
    public Result crpModuleGetById(@PathVariable Integer id) {
        CrpModule crpModule = crpModuleService.getById(id);
        return Result.success(crpModule);
    }

    /**
     * 新增模块
     */
    @PostMapping("/crp-module-add")
    public Result crpModuleAdd(@RequestBody CrpModule crpModule) {
        crpModuleService.save(crpModule);
        return Result.success();
    }

    /**
     * 修改模块
     */
    @PostMapping("/crp-module-update")
    public Result crpModuleUpdate(@RequestBody CrpModule crpModule) {
        if (crpModule.getId() <= 4) {
            return Result.fail("禁止修改");
        }
        crpModuleService.updateById(crpModule);
        return Result.success();
    }

    /**
     * 删除模块
     */
    @DeleteMapping("/crp-module-delete/{id}")
    public Result crpModuleDeleteById(@PathVariable Integer id) {
        if (id <= 4) {
            return Result.fail("禁止删除");
        }
        crpModuleService.removeById(id);
        return Result.success();
    }

    /**
     * 批量删除模块
     */
    @Deprecated
    @DeleteMapping("/crp-module-delete-batch/")
    public Result crpModuleDelete(List<Integer> ids) {
        System.out.println(ids);
        return Result.success();
    }


    /**
     * 获取所有培养项目，带有分页
     */
    @GetMapping("/crp-item-list")
    public Result crpItemList(
            @RequestParam(value = "key", required = false, defaultValue = "") String key,
            @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
            @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
            @RequestParam(value = "mid", required = false, defaultValue = "") String mid) {

        List<CrpItem1> list = crpItemService.listByPage(key, mid, page, size);
        PageInfo<CrpItem1> info = new PageInfo<>(list);
        return Result.success(info);
    }


    /**
     * 获取单个培养项目
     */
    @GetMapping("/crp-item/{id}")
    public Result crpItemGetById(@PathVariable String id) {
        CrpItem1 crpItem1 = crpItemService.getItemAndModById(id);
        return Result.success(crpItem1);
    }


    /**
     * 新增培养项目
     */
    @PostMapping("/crp-item-add")
    public Result crpItemAdd(@RequestBody CrpItem crpItem) {
        crpItemService.save(crpItem);
        return Result.success();
    }

    /**
     * 修改培养项目
     */
    @PostMapping("/crp-item-update")
    public Result crpItemUpdate(@RequestBody CrpItem crpItem) {
        if (crpItem.getId() <= 38) {
            return Result.fail("禁止修改");
        }
        crpItemService.updateById(crpItem);
        return Result.success();
    }

    /**
     * 删除培养项目
     */
    @DeleteMapping("/crp-item-delete/{id}")
    public Result crpItemDeleteById(@PathVariable Integer id) {
        if (id <= 38) {
            return Result.fail("禁止删除");
        }
        crpItemService.removeById(id);
        return Result.success();
    }


    /**
     * 获取所有班级，带有分页
     */
    @GetMapping("/class-list")
    public Result clazzList(
            @RequestParam(value = "key", required = false, defaultValue = "") String key,
            @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
            @RequestParam(value = "size", required = false, defaultValue = "10") Integer size) {

        List<Class1> list = classService.listByPage(key, page, size);
        PageInfo<Class1> info = new PageInfo<>(list);
        return Result.success(info);
    }


    /**
     * 获取单个班级
     */
    @GetMapping("/class/{id}")
    public Result clazzGetById(@PathVariable String id) {
        Class1 clazz1 = classService.getClassInfoById(id);
        return Result.success(clazz1);
    }


    /**
     * 新增班级
     */
    @PostMapping("/class-add")
    public Result clazzAdd(@RequestBody Class clazz) {
        // 通过 class id 查询是否有当前学生
        Student stuInDb = studentService.getById(clazz.getClassAdminStudentId());
        if (stuInDb == null) {
            clazz.setClassAdminStudentId(null);
        } else {
            // 当前学生是否为当前班级
            if (!stuInDb.getClassId().equals(clazz.getId())) {
                clazz.setClassAdminStudentId(null);
            }
        }

        classService.save(clazz);
        return Result.success();
    }

    /**
     * 修改班级
     */
    @PostMapping("/class-update")
    public Result clazzUpdate(@RequestBody Class clazz) {
        // 通过 class id 查询是否有当前学生
        Student stuInDb = studentService.getById(clazz.getClassAdminStudentId());
        if (stuInDb == null) {
            clazz.setClassAdminStudentId(null);
        } else {
            // 当前学生是否为当前班级
            if (!stuInDb.getClassId().equals(clazz.getId())) {
                clazz.setClassAdminStudentId(null);
            }
        }
        classService.updateById(clazz);
        return Result.success();
    }

    /**
     * 删除班级
     */
    @DeleteMapping("/class-delete/{id}")
    public Result clazzDeleteById(@PathVariable Integer id) {
        classService.removeById(id);
        return Result.success();
    }

    /**
     * 获取所有部门，带有分页
     */
    @GetMapping("/department-list")
    public Result departmentList(
            @RequestParam(value = "key", required = false, defaultValue = "") String key,
            @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
            @RequestParam(value = "size", required = false, defaultValue = "10") Integer size) {

        List<Department1> list = departmentService.listByPage(key, page, size);
        PageInfo<Department1> info = new PageInfo<>(list);
        return Result.success(info);
    }


    /**
     * 获取单个部门
     */
    @GetMapping("/department/{id}")
    public Result departmentGetById(@PathVariable String id) {
        Department1 department1 = departmentService.getDepartmentInfoById(id);
        return Result.success(department1);
    }


    /**
     * 新增部门
     */
    @PostMapping("/department-add")
    public Result departmentAdd(@RequestBody Department department) {
        department.setDepartmentAdminStudentId(null);
        departmentService.save(department);
        return Result.success();
    }

    /**
     * 修改部门
     */
    @PostMapping("/department-update")
    public Result departmentUpdate(@RequestBody Department department) {
        // todo 判断当前学生是否为部门管理员
        departmentService.updateById(department);
        return Result.success();
    }

    /**
     * 删除部门
     */
    @DeleteMapping("/department-delete/{id}")
    public Result departmentDeleteById(@PathVariable Integer id) {
        departmentService.removeById(id);
        return Result.success();
    }


    /**
     * 获取所有学生，带有分页
     */
    @GetMapping("/student-list")
    public Result studentList(
            @RequestParam(value = "key", required = false, defaultValue = "") String key,
            @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
            @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
            @RequestParam(value = "cid", required = false, defaultValue = "") String cid) {

        List<StudentInfo> list = studentService.listByPage(key, cid, page, size);
        PageInfo<StudentInfo> info = new PageInfo<>(list);
        return Result.success(info);
    }


    /**
     * 获取单个学生
     */
    @GetMapping("/student/{id}")
    public Result studentGetById(@PathVariable String id) {
        StudentInfo student1 = studentService.studentInfo(id);
        return Result.success(student1);
    }


    /**
     * 新增学生
     */
    @PostMapping("/student-add")
    public Result studentAdd(@RequestBody Student student) {
        studentService.save(student);
        return Result.success();
    }

    /**
     * 修改学生
     */
    @PostMapping("/student-update")
    public Result studentUpdate(@RequestBody Student student) {
        studentService.updateById(student);
        return Result.success();
    }

    /**
     * 删除学生
     */
    @DeleteMapping("/student-delete/{id}")
    public Result studentDeleteById(@PathVariable String id) {
        studentService.removeById(id);
        return Result.success();
    }

    /**
     * 导出学生Excel模板
     * class_id
     * student_name
     * email
     */
    @GetMapping("/student-template")
    public void exportStudentTemplate(HttpServletResponse response) throws Exception {
        List<Student> studentList = new ArrayList<>();
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里 URLEncoder.encode 可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("学生模板", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), Student.class).sheet("模板").doWrite(studentList);
    }

    /**
     * 导入Excel模板
     */
    @PostMapping("/student-upload-excel")
    public Result importStudentTemplate(MultipartFile file) throws Exception {
        EasyExcel.read(file.getInputStream(), Student.class, new StudentUploadListener(studentService)).sheet().doRead();
        return Result.success();
    }

    /**
     * 获取所有CRP 申请，查询某个班级所有，带有分页
     */
    @GetMapping("/crp-list")
    public Result crpList(
            @RequestParam(value = "key", required = false, defaultValue = "") String key,
            @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
            @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
            @RequestParam(value = "cid", required = false, defaultValue = "") String classId) {

        List<ScoreRecord1> list = scoreRecordService.listByPage(key, classId, page, size);
        PageInfo<ScoreRecord1> info = new PageInfo<>(list);
        return Result.success(info);
    }


    /**
     * 获取单个CRP 申请
     */
    @GetMapping("/crp/{id}")
    public Result crpGetById(@PathVariable String id) {
        ScoreRecord1 record1 = scoreRecordService.crpInfoById(id);
        return Result.success(record1);
    }

    /**
     * 修改CRP 申请
     */
    @PostMapping("/crp-update-state")
    public Result crpUpdate(@RequestBody ScoreRecord record) {
        LambdaUpdateWrapper<ScoreRecord> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(ScoreRecord::getState, record.getState());
        wrapper.set(ScoreRecord::getReviewTime, LocalDateTime.now());
        wrapper.eq(ScoreRecord::getId, record.getId());
        scoreRecordService.update(wrapper);
        return Result.success();
    }

    /**
     * 通过部门id查询部门成员
     */
    @GetMapping("dep-stu-list")
    public Result depStuList(@RequestParam(value = "key", required = false, defaultValue = "") String key,
                             @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
                             @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
                             @RequestParam(value = "depId", required = false, defaultValue = "") String depId) {
        List<DepStu1> list = departmentService.depStuListByPage(key, depId, size, page);
        PageInfo<DepStu1> info = new PageInfo<>(list);
        return Result.success(info);
    }
}
